package com.bdth.bdthiss.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.bdth.bdthiss.entity.Contract;
import com.bdth.bdthiss.entity.User;
import com.bdth.bdthiss.service.ContractService;
import com.bdth.bdthiss.util.DateUtil;
import com.bdth.bdthiss.vo.HtPie;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.Title;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.Orient;
import com.github.abel533.echarts.code.Trigger;
import com.github.abel533.echarts.series.*;
import com.github.abel533.echarts.style.ItemStyle;
import com.github.abel533.echarts.style.itemstyle.Emphasis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

@RestController
public class EchartsController {

    @Autowired
    private ContractService contractService;

    @RequestMapping(value = "/map", method = RequestMethod.GET)
    public Map<String, Object> getMap() throws JsonProcessingException {
        Map<String, Object> map = new HashMap<>(3);
        User user = new User();
        map.put("作者信息", user);
        map.put("博客地址", "http://blog.itcodai.com");
        map.put("CSDN地址", null);
        map.put("粉丝数量", 1);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(map);
        return map;
    }

    /**
     * 销售比例
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping(value = "/page/pagePie",produces="application/json;charset=UTF-8")
    public String pagePie() throws JsonProcessingException {
        //获取当天日期
        LocalDate date = LocalDate.now();
        Integer year = date.getYear();
        EntityWrapper<Contract> entityWrapper = new EntityWrapper<>();
        entityWrapper.ge("crtime",year+"-01-01");
        entityWrapper.le("crtime",year+"-12-31");
        List<Contract> list = contractService.selectList(entityWrapper);
        Map<String, Double> map = list.stream().collect(Collectors.groupingBy(o -> o.getSignman(), Collectors.summingDouble(p -> p.getTotal().doubleValue())));
        Option option = new Option();
        List<String> listKey = new ArrayList<>();
        for (Map.Entry<String, Double> entry:map.entrySet()){
            listKey.add(entry.getKey());
        }
        option.legend().setData(listKey);
        option.legend().orient(Orient.horizontal);

        option.tooltip().trigger(Trigger.item).formatter("{a} {b} : {c} ({d}%)");

        Pie pie = new Pie();
        pie.name("销售比例");
        pie.radius("55%");
        pie.center(new String[]{ "50%","50%"});
        for (Map.Entry<String, Double> entry:map.entrySet()) {
            HtPie htPie = new HtPie(entry.getKey(),entry.getValue());
            pie.data().add(htPie);
        }
        option.series(pie);

        ItemStyle itemStyle = new ItemStyle();
        Emphasis emphasis = new Emphasis();
        emphasis.setShadowBlur(10);
        emphasis.setShadowOffsetX(0);
        emphasis.setShadowColor("rgba(0, 0, 0, 0.5)");
        itemStyle.setEmphasis(emphasis);
        option.setItemStyle(itemStyle);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(option);
        System.out.println(value);
        return value;
    }

    /**
     * 19年度销售比例
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping(value = "/page/pagePie19",produces="application/json;charset=UTF-8")
    public String pagePie19() throws JsonProcessingException {
        //获取当天日期
        LocalDate date = LocalDate.now();
        Integer year = 2019;
        EntityWrapper<Contract> entityWrapper = new EntityWrapper<>();
        entityWrapper.ge("crtime",year+"-01-01");
        entityWrapper.le("crtime",year+"-12-31");
        List<Contract> list = contractService.selectList(entityWrapper);
        Map<String, Double> map = list.stream().collect(Collectors.groupingBy(o -> o.getSignman(), Collectors.summingDouble(p -> p.getTotal().doubleValue())));
        Option option = new Option();
        List<String> listKey = new ArrayList<>();
        for (Map.Entry<String, Double> entry:map.entrySet()){
            listKey.add(entry.getKey());
        }
        option.legend().setData(listKey);
        option.legend().orient(Orient.horizontal);

        option.tooltip().trigger(Trigger.item).formatter("{a} {b} : {c} ({d}%)");

        Pie pie = new Pie();
        pie.name("销售比例");
        pie.radius("55%");
        pie.center(new String[]{ "50%","50%"});
        for (Map.Entry<String, Double> entry:map.entrySet()) {
            HtPie htPie = new HtPie(entry.getKey(),entry.getValue());
            pie.data().add(htPie);
        }
        option.series(pie);

        ItemStyle itemStyle = new ItemStyle();
        Emphasis emphasis = new Emphasis();
        emphasis.setShadowBlur(10);
        emphasis.setShadowOffsetX(0);
        emphasis.setShadowColor("rgba(0, 0, 0, 0.5)");
        itemStyle.setEmphasis(emphasis);
        option.setItemStyle(itemStyle);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(option);
        System.out.println(value);
        return value;
    }

    /**
     * 月销售额柱状图
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping(value = "/page/pageBar",produces="application/json;charset=UTF-8")
    public String pageBar() throws JsonProcessingException {
        //获取当天日期
        LocalDate date = LocalDate.now();
        Integer year = date.getYear();
        Integer lastYear = year-1;
        EntityWrapper<Contract> entityWrapper = new EntityWrapper<>();
        entityWrapper.ge("crtime",lastYear+"-01-01");
        entityWrapper.le("crtime",year+"-12-31");
        List<Contract> list = contractService.selectList(entityWrapper);
        Map<String, Double> map = list.stream().collect(Collectors.groupingBy(o -> DateUtil.getYM(o.getCrtime()), Collectors.summingDouble(p -> p.getTotal().doubleValue())));
        Option option = new Option();
        Title title = new Title();
        title.setText("");
        title.setSubtext("单位：万元");
        option.title(title);

        option.legend().data(lastYear+"年",year+"年").orient(Orient.horizontal);

        option.tooltip().trigger(Trigger.axis);
        List<String> xList = Arrays.asList("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");
        //x坐标
        CategoryAxis categoryAxis = new CategoryAxis();
        for(String x:xList)
            categoryAxis.data().add(x);
        option.xAxis(categoryAxis);
        //y坐标
        ValueAxis valueAxis = new ValueAxis();
        option.yAxis(valueAxis);

        List<Number> lineValue1 = Arrays.asList(getValue(map,year+"-01"),
                getValue(map,lastYear+"-02"),
                getValue(map,lastYear+"-03"),
                getValue(map,lastYear+"-04"),
                getValue(map,lastYear+"-05"),
                getValue(map,lastYear+"-06"),
                getValue(map,lastYear+"-07"),
                getValue(map,lastYear+"-08"),
                getValue(map,lastYear+"-09"),
                getValue(map,lastYear+"-10"),
                getValue(map,lastYear+"-11"),
                getValue(map,lastYear+"-12"));
        List<Number> lineValue2 = Arrays.asList(
                getValue(map,year+"-01"),
                getValue(map,year+"-02"),
                getValue(map,year+"-03"),
                getValue(map,year+"-04"),
                getValue(map,year+"-05"),
                getValue(map,year+"-06"),
                getValue(map,year+"-07"),
                getValue(map,year+"-08"),
                getValue(map,year+"-09"),
                getValue(map,year+"-10"),
                getValue(map,year+"-11"),
                getValue(map,year+"-12"));
        Map<String,List<Number>> mapLine = new HashMap<>();
        mapLine.put(lastYear+"年",lineValue1);
        mapLine.put(year+"年",lineValue2);

        for(Map.Entry<String, List<Number>> entry : mapLine.entrySet()){
            Bar bar = new Bar();
            bar.name(entry.getKey());
            for(Number n:entry.getValue())
                bar.data().add(n);
            option.series(bar);
        }

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(option);
        System.out.println(value);
        return value;
    }

    /**
     * 19年度月销售额柱状图
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping(value = "/page/pageBar19",produces="application/json;charset=UTF-8")
    public String pageBar19() throws JsonProcessingException {
        //获取当天日期
        LocalDate date = LocalDate.now();
        Integer year = 2019;
        Integer lastYear = 2018;
        EntityWrapper<Contract> entityWrapper = new EntityWrapper<>();
        entityWrapper.ge("crtime",year+"-01-01");
        entityWrapper.le("crtime",year+"-12-31");
        List<Contract> list = contractService.selectList(entityWrapper);
        Map<String, Double> map = list.stream().collect(Collectors.groupingBy(o -> DateUtil.getYM(o.getCrtime()), Collectors.summingDouble(p -> p.getTotal().doubleValue())));
        Option option = new Option();
        Title title = new Title();
        title.setText("");
        title.setSubtext("单位：万元");
        option.title(title);

        option.legend().data(lastYear+"年",year+"年").orient(Orient.horizontal);

        option.tooltip().trigger(Trigger.axis);
        List<String> xList = Arrays.asList("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");
        //x坐标
        CategoryAxis categoryAxis = new CategoryAxis();
        for(String x:xList)
            categoryAxis.data().add(x);
        option.xAxis(categoryAxis);
        //y坐标
        ValueAxis valueAxis = new ValueAxis();
        option.yAxis(valueAxis);

        List<Number> lineValue1 = Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        List<Number> lineValue2 = Arrays.asList(
                getValue(map,year+"-01"),
                getValue(map,year+"-02"),
                getValue(map,year+"-03"),
                getValue(map,year+"-04"),
                getValue(map,year+"-05"),
                getValue(map,year+"-06"),
                getValue(map,year+"-07"),
                getValue(map,year+"-08"),
                getValue(map,year+"-09"),
                getValue(map,year+"-10"),
                getValue(map,year+"-11"),
                getValue(map,year+"-12"));
        Map<String,List<Number>> mapLine = new HashMap<>();
        mapLine.put(lastYear+"年",lineValue1);
        mapLine.put(year+"年",lineValue2);

        for(Map.Entry<String, List<Number>> entry : mapLine.entrySet()){
            Bar bar = new Bar();
            bar.name(entry.getKey());
            for(Number n:entry.getValue())
                bar.data().add(n);
            option.series(bar);
        }

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(option);
        System.out.println(value);
        return value;
    }

    private Double getValue(Map<String, Double> map ,String key){
        if(map.get(key)!=null){
            DecimalFormat df = new DecimalFormat("#.00");
            return Double.valueOf(df.format(map.get(key)/10000));
        }
        return 0.0;
    }

    private Long getLongValue(Map<String, Long> map ,String key){
        if(map.get(key)!=null){
            return map.get(key);
        }
        return 0L;
    }

    /**
     * 近10天的合同数量曲线及合同金额
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping(value = "/page/pageHtSum",produces="application/json;charset=UTF-8")
    public String pageHtSum() throws JsonProcessingException {
        //算出10天前的日期
        LocalDate date = LocalDate.now();
        LocalDate date10 = date.minusDays(10);

        EntityWrapper<Contract> entityWrapper = new EntityWrapper<>();
        entityWrapper.ge("crtime",date10);
        entityWrapper.le("crtime",date);
        List<Contract> list = contractService.selectList(entityWrapper);
        Map<String, Double> map = list.stream().collect(Collectors.groupingBy(o -> DateUtil.format(o.getCrtime()), Collectors.summingDouble(p -> p.getTotal().doubleValue())));
        Map<String, Long> mapcount = list.stream().collect(Collectors.groupingBy(o -> DateUtil.format(o.getCrtime()),Collectors.counting()));
        Option option = new Option();
        //默认横向布局，纵向布局值为'vertical'
        //orient:'horizontal'
        option.legend().right("10%").data("合同数量","合同金额").orient(Orient.vertical);

//        option.toolbox().show(true).feature(Tool.dataZoom,Tool.dataView,Tool.saveAsImage);
//        option.toolbox().show(true).feature().put(String.valueOf(Tool.dataZoom),dataZoom.yAxisIndex("none"));
        option.calculable(true);
        option.tooltip().trigger(Trigger.axis);

        List<String> xList = DateUtil.getLocalDateByDayStr(date10,date);
        //x坐标
        CategoryAxis categoryAxis = new CategoryAxis();
        categoryAxis.boundaryGap(false);
        for(String x:xList)
            categoryAxis.data().add(x);
        option.xAxis(categoryAxis);

        //y坐标
        ValueAxis valueAxis = new ValueAxis();
        valueAxis.axisLabel().formatter("{value}");
        option.yAxis(valueAxis);

        List<Number> lineValue1 = Arrays.asList(
                getValue(map,DateUtil.format(date.minusDays(10))),
                getValue(map,DateUtil.format(date.minusDays(9))),
                getValue(map,DateUtil.format(date.minusDays(8))),
                getValue(map,DateUtil.format(date.minusDays(7))),
                getValue(map,DateUtil.format(date.minusDays(6))),
                getValue(map,DateUtil.format(date.minusDays(5))),
                getValue(map,DateUtil.format(date.minusDays(4))),
                getValue(map,DateUtil.format(date.minusDays(3))),
                getValue(map,DateUtil.format(date.minusDays(2))),
                getValue(map,DateUtil.format(date.minusDays(1))),
                getValue(map,DateUtil.format(date.minusDays(0)))
        );
        List<Number> lineValue2 = Arrays.asList(
                getLongValue(mapcount,DateUtil.format(date.minusDays(10))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(9))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(8))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(7))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(6))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(5))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(4))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(3))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(2))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(1))),
                getLongValue(mapcount,DateUtil.format(date.minusDays(0)))
        );
        Map<String,List<Number>> mapLine = new HashMap<>();
        mapLine.put("合同数量",lineValue1);
        mapLine.put("合同金额",lineValue2);

        for(Map.Entry<String, List<Number>> entry : mapLine.entrySet()){
            Line line = new Line();
            line.name(entry.getKey());
//            for(Number n:entry.getValue())
//                line.data().add(n);
//            line.markLine(getMarkLine("平均值","average"));
//            if(entry.getKey().equals("最高价"))
//                line.markPoint(getMarkPoint("最大值","max"));
//            if(entry.getKey().equals("最低价"))
//                line.markPoint(getMarkPoint("最小值","min"));
            option.series(line);
        }

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(option);
        System.out.println(value);
        return value;
    }

    /**
     * 近10笔的合同金额
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping(value = "/page/pageHtTotal",produces="application/json;charset=UTF-8")
    public String pageHtTotal() throws JsonProcessingException {
        //算出10天前的日期
        LocalDate date = LocalDate.now();
        EntityWrapper<Contract> entityWrapper = new EntityWrapper<>();
        entityWrapper.orderBy("crtime",false);
        entityWrapper.last("limit 10");
        List<Contract> list = contractService.selectList(entityWrapper);
        //Map<String, Double> map = list.stream().collect(Collectors.groupingBy(o -> DateUtil.format(o.getCrtime()), Collectors.summingDouble(p -> p.getTotal().doubleValue())));
        Option option = new Option();
        //默认横向布局，纵向布局值为'vertical'
        //orient:'horizontal'
        option.legend().right("10%").data("合同金额").orient(Orient.vertical);

        Title title = new Title();
        title.setText("");
        title.setSubtext("单位：万元");
        option.title(title);

        option.calculable(true);
        option.tooltip().trigger(Trigger.axis);

        List<String> xList = DateUtil.getLocalDateByDayStr(date.minusDays(9),date);
        //x坐标
        CategoryAxis categoryAxis = new CategoryAxis();
        categoryAxis.boundaryGap(false);
        for(String x:xList)
            categoryAxis.data().add(x);
        option.xAxis(categoryAxis);

        //y坐标
        ValueAxis valueAxis = new ValueAxis();
        valueAxis.axisLabel().formatter("{value}");
        option.yAxis(valueAxis);
        List<Number> lineValue1 = list.stream().map(o->o.getTotal().divide(new BigDecimal(10000.0))).collect(Collectors.toList());
        Map<String,List<Number>> mapLine = new HashMap<>();
        mapLine.put("合同金额",lineValue1);

        for(Map.Entry<String, List<Number>> entry : mapLine.entrySet()){
            Line line = new Line();
            line.name(entry.getKey());
            for(Number n:entry.getValue())
                line.data().add(n);
//            line.markLine(getMarkLine("平均值","average"));
//            if(entry.getKey().equals("最高价"))
//                line.markPoint(getMarkPoint("最大值","max"));
//            if(entry.getKey().equals("最低价"))
//                line.markPoint(getMarkPoint("最小值","min"));
            option.series(line);
        }

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(option);
        System.out.println(value);
        return value;
    }

    @RequestMapping(value = "/page/pageLine",produces="application/json;charset=UTF-8")
    public String pageLine() throws JsonProcessingException {
        Option option = new Option();
        Title title = new Title();
        title.setText("-");
        title.setSubtext("-");
        option.title(title);
        //默认横向布局，纵向布局值为'vertical'
        //orient:'horizontal'
        option.legend().right("10%").data("最高价","最低价").orient(Orient.vertical);

//        option.toolbox().show(true).feature(Tool.dataZoom,Tool.dataView,Tool.saveAsImage);
//        option.toolbox().show(true).feature().put(String.valueOf(Tool.dataZoom),dataZoom.yAxisIndex("none"));
        option.calculable(true);
        option.tooltip().trigger(Trigger.axis);
        List<String> xList = Arrays.asList("周日","周一","周二","周三","周四","周五","周六");
        //x坐标
        CategoryAxis categoryAxis = new CategoryAxis();
        categoryAxis.boundaryGap(false);
        for(String x:xList)
            categoryAxis.data().add(x);
        option.xAxis(categoryAxis);

        //y坐标
        ValueAxis valueAxis = new ValueAxis();
        valueAxis.axisLabel().formatter("{value}");
        option.yAxis(valueAxis);

        List<Number> lineValue1 = Arrays.asList(15, 20, 32, 16, 12, 32, 37);
        List<Number> lineValue2 = Arrays.asList(15, 12, 16, 6, 7, 8, 17);
        Map<String,List<Number>> mapLine = new HashMap<>();
        mapLine.put("最高价",lineValue1);
        mapLine.put("最低价",lineValue2);

        for(Map.Entry<String, List<Number>> entry : mapLine.entrySet()){
            Line line = new Line();
            line.name(entry.getKey());
            for(Number n:entry.getValue())
                line.data().add(n);
            line.markLine(getMarkLine("平均值","average"));
            if(entry.getKey().equals("最高价"))
                line.markPoint(getMarkPoint("最大值","max"));
            if(entry.getKey().equals("最低价"))
                line.markPoint(getMarkPoint("最小值","min"));
            option.series(line);
        }

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String value = objectMapper.writeValueAsString(option);
        System.out.println(value);
        return value;
    }

    private MarkLine getMarkLine(String name,String type){
        MarkLine markLine = new MarkLine();
        List<Map<String,String>> listMap = getListMap(name,type);
        markLine.setData(listMap);
        return markLine;
    }

    private MarkPoint getMarkPoint(String name,String type){
        MarkPoint markPoint = new MarkPoint();
        List<Map<String,String>> listMap = getListMap(name,type);
        markPoint.setData(listMap);
        return markPoint;
    }

    private List<Map<String,String>> getListMap(String name,String type){
        List<Map<String,String>> list = new ArrayList<>();
        Map<String,String> map = new HashMap<>();
        map.put("type",type);
        map.put("name",name);
        list.add(map);
        return list;
    }
}
